<!DOCTYPE html>
<html lang="zh-CN">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Deepseek API 前端示例</title>
	<style>
		body {
			font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
			max-width: 800px;
			margin: 0 auto;
			padding: 20px;
			background-color: #f5f5f5;
		}
		h1 {
			color: #333;
			text-align: center;
		}
		.chat-container {
			background-color: white;
			border-radius: 8px;
			padding: 20px;
			box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
		}
		.messages {
			height: 400px;
			overflow-y: auto;
			margin-bottom: 20px;
			padding: 10px;
			border: 1px solid #ddd;
			border-radius: 5px;
		}
		.message {
			margin-bottom: 15px;
			padding: 10px;
			border-radius: 5px;
		}
		.user {
			background-color: #e1f5fe;
			margin-left: 20%;
			text-align: right;
		}
		.assistant {
			background-color: #f1f1f1;
			margin-right: 20%;
		}
		.input-area {
			display: flex;
			gap: 10px;
		}
		input {
			flex: 1;
			padding: 10px;
			border: 1px solid #ddd;
			border-radius: 5px;
			font-size: 16px;
		}
		button {
			padding: 10px 20px;
			background-color: #2196f3;
			color: white;
			border: none;
			border-radius: 5px;
			cursor: pointer;
			font-size: 16px;
		}
		button:disabled {
			background-color: #b0bec5;
			cursor: not-allowed;
		}
		.loading {
			color: #666;
			font-style: italic;
		}
		.controls {
			display: flex;
			justify-content: space-between;
			margin-bottom: 20px;
		}
		.toggle-btn {
			background-color: #4caf50;
		}
	</style>
</head>
<body>
	<h1>Deepseek API 前端示例</h1>
	
	<div class="chat-container">
		<div class="controls">
			<button id="clearBtn">清空对话</button>
			<button id="toggleStreamBtn" class="toggle-btn">流式输出: 开</button>
		</div>
		
		<div id="messages" class="messages"></div>
		
		<div class="input-area">
			<input 
				id="userInput" 
				type="text" 
				placeholder="输入消息..." 
				autofocus
			/>
			<button id="sendBtn">发送</button>
		</div>
	</div>

	<script>
		// 元素引用
		const messagesContainer = document.getElementById('messages');
		const userInput = document.getElementById('userInput');
		const sendBtn = document.getElementById('sendBtn');
		const clearBtn = document.getElementById('clearBtn');
		const toggleStreamBtn = document.getElementById('toggleStreamBtn');
		
		// 状态变量
		let isLoading = false;
		let useStream = true;
		let chatHistory = [];
		
		// 事件监听
		sendBtn.addEventListener('click', sendMessage);
		clearBtn.addEventListener('click', clearChat);
		toggleStreamBtn.addEventListener('click', toggleStream);
		userInput.addEventListener('keypress', (e) => {
			if (e.key === 'Enter') sendMessage();
		});
		
		// 切换流式输出
		function toggleStream() {
			useStream = !useStream;
			toggleStreamBtn.textContent = `流式输出: ${useStream ? '开' : '关'}`;
		}
		
		// 清空聊天记录
		function clearChat() {
			chatHistory = [];
			messagesContainer.innerHTML = '';
		}
		
		// 添加消息到界面
		function addMessage(role, content) {
			const messageDiv = document.createElement('div');
			messageDiv.className = `message ${role}`;
			messageDiv.textContent = content;
			messagesContainer.appendChild(messageDiv);
			messagesContainer.scrollTop = messagesContainer.scrollHeight;
			
			// 添加到历史记录
			if (role !== 'loading') {
				chatHistory.push({ role, content });
			}
		}
		
		// 发送消息
		async function sendMessage() {
			const message = userInput.value.trim();
			if (!message || isLoading) return;
			
			// 清空输入框
			userInput.value = '';
			
			// 显示用户消息
			addMessage('user', message);
			
			// 准备发送的消息
			const messages = [
				{ role: 'system', content: '你是一个有用的AI助手。' },
				...chatHistory.map(msg => ({
					role: msg.role === 'user' ? 'user' : 'assistant',
					content: msg.content
				}))
			];
			
			// 显示加载状态
			isLoading = true;
			sendBtn.disabled = true;
			const loadingId = 'loading-' + Date.now();
			addMessage('loading', 'AI正在思考...');
			
			try {
				if (useStream) {
					await sendStreamRequest(messages);
				} else {
					await sendNormalRequest(messages);
				}
			} catch (error) {
				console.error('请求失败:', error);
				addMessage('assistant', '抱歉，请求失败，请稍后再试。');
			} finally {
				// 移除加载提示
				const loadingMsg = document.querySelector('.loading');
				if (loadingMsg) {
					messagesContainer.removeChild(loadingMsg);
				}
				isLoading = false;
				sendBtn.disabled = false;
			}
		}
		
		// 发送非流式请求
		async function sendNormalRequest(messages) {
			const response = await fetch('http://localhost:3000/v1/chat/completions', {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json',
				},
				body: JSON.stringify({
					messages,
					stream: false,
					temperature: 0.7
				})
			});
			
			const data = await response.json();
			addMessage('assistant', data.content);
		}
		
		// 发送流式请求
		async function sendStreamRequest(messages) {
			const response = await fetch('http://localhost:3000/v1/chat/completions', {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json',
				},
				body: JSON.stringify({
					messages,
					stream: true,
					temperature: 0.7
				})
			});
			
			// 创建AI回复的消息容器
			const messageDiv = document.createElement('div');
			messageDiv.className = 'message assistant';
			messagesContainer.appendChild(messageDiv);
			
			// 获取响应流
			const reader = response.body.getReader();
			const decoder = new TextDecoder();
			let fullResponse = '';
			
			// 处理流式响应
			while (true) {
				const { done, value } = await reader.read();
				if (done) break;
				
				// 解码二进制数据
				const text = decoder.decode(value);
				
				// 处理返回的数据行
				const lines = text.split('\n').filter(line => line.trim());
				for (const line of lines) {
					try {
						const data = JSON.parse(line);
						console.log("🚀 ~ sendStreamRequest ~ data:", data.content)
						if (data.content) {
							fullResponse += data.content;
							messageDiv.textContent = fullResponse;
							messagesContainer.scrollTop = messagesContainer.scrollHeight;
						}
					} catch (e) {
						console.error('解析JSON失败:', e);
					}
				}
			}
			
			// 添加完整回复到历史记录
			chatHistory.push({ role: 'assistant', content: fullResponse });
		}
	</script>
</body>
</html> 